package org.easystub.dbstub;


import java.sql.*;

public class InsertBuilder {
    private final String tableName;
    private final Connection connection;
    private final String schema;
    private String[] columns;
    private Integer lastGeneratedPrimaryKey;

    public InsertBuilder(String tableName, Connection connection, String schema) throws SQLException {
        this.schema = schema;
        this.tableName = tableName;
        this.connection = connection;
    }

    public InsertBuilder usingColumns(String... columns) {
        this.columns = columns;
        return this;
    }

    public InsertBuilder values(Object... values) {

        StringBuilder sql = new StringBuilder();
        sql.append("insert into ");
        sql.append(schema);
        sql.append(".");
        sql.append(tableName);

        if(columns != null && columns.length > 0) {
            appendColumnNames(sql);
        }

        sql.append(" values(");

        for (Object value : values) {
            sql.append("?,");
        }

        sql.deleteCharAt(sql.length() - 1);

        sql.append(")");

        try {
            PreparedStatement ps = connection.prepareStatement(sql.toString(), Statement.RETURN_GENERATED_KEYS);
            for (int i = 0; i < values.length; i++) {
                ps.setObject(i + 1, values[i]);
            }

            ps.execute();
            storeGeneratedKeys(ps);
        } catch (SQLException e) {
            throw new DBStubException(e);
        }

        return this;
    }

    private void storeGeneratedKeys(PreparedStatement ps) throws SQLException {
        ResultSet keys = ps.getGeneratedKeys();
        if(keys.next()) {
            lastGeneratedPrimaryKey = keys.getInt(1);
        }
    }

    private void appendColumnNames(StringBuilder sql) {
        sql.append("(");
        for (String columnName : columns) {
            sql.append(columnName);
            sql.append(",");
        }
        sql.deleteCharAt(sql.length() - 1);
        sql.append(")");
    }

    public Integer getLastGeneratedPrimaryKey() {
        return lastGeneratedPrimaryKey;
    }
}
